/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { Component } from "react";
import {
  Table,
  InputNumber,
  Form,
  Select,
  Modal,
  Radio,
  Row,
  Col,
  Avatar,
  message,
} from "antd";
import { names } from "@/components/KbSource/config.js";
import { connect } from "dva";
import { cloneDeep } from "lodash";
import styles from "./editTable.less";

const { Option, OptGroup } = Select;

const EditableContext = React.createContext();

const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);
const textStyle = {
  whiteSpace: "nowrap",
  textOverflow: "ellipsis",
  overflow: "hidden",
};

class EditableCell extends Component {
  state = {
    editing: false,
    visible: false,
    is_infinite: 1,
    addOrCut: "increase",
    quantity: null, // 用户输入的增加或减少的单号数量展示
    quantityForCalculate: null, // 用于单号数量计算，传递给后端
    quantityForShow: 0, // 表格中单号总数量的展示
    quantityChanged: false, // 用户是否输入单号数量
  };

  componentDidMount() {
    const { record } = this.props;
    if (record) {
      if (record.waybill_quantity != undefined) {
        // 防止当waybill_quantity为undefined时，导致修改后的单号总数量不同步显示
        this.setState({
          quantityForShow: record.waybill_quantity,
          is_infinite: record.waybill_quantity < 0 ? 1 : 0,
        });
      } else {
        this.setState({ quantityForShow: -1, is_infinite: 1 });
      }
    }
  }

  componentDidUpdate(prevProps) {
    const { record } = this.props;
    const oldProps = prevProps.record.hasSelected;
    const newProps = record.hasSelected;
    if (oldProps !== newProps && newProps) {
      this.setState({
        is_infinite: 1,
        quantityForShow: -1,
        quantityForCalculate: null,
        quantity: null,
      }); // 执行多次待优化
    }
  }

  save = e => {
    const { record, handleSave } = this.props;
    // 最初始的单号数量
    const orign_waybill_quantity = Number(
      !record.waybill_quantity || record.waybill_quantity == -1 ? 0 : record.waybill_quantity
    );

    this.form.validateFields((error, fieldValues) => {
      const quantityForShow =
        fieldValues.quantityForShow !== undefined
          ? fieldValues.quantityForShow
          : orign_waybill_quantity;
      if (error && error[e.currentTarget.id]) {
        return;
      }

      fieldValues.source = record.source;
      fieldValues.source_type = record.source.source_type;
      fieldValues.auth_id = record.source.auth_id;
      fieldValues.brand =
        record.source.brand ||
        record.source.brand_code ||
        record.source.brand_type ||
        record.source.kb_code;
      fieldValues.is_infinite = quantityForShow < 0 ? "1" : "0";
      fieldValues.quantity = quantityForShow - orign_waybill_quantity;
      fieldValues.hasSelected = false; // 防止单号源切换后，表格剩余数据不可编辑
      this.toggleEdit(false);
      handleSave({ ...cloneDeep(record), ...fieldValues }, this.props);
    });
  };

  toggleEdit = open => {
    this.setState({ editing: open }, () => {
      if (open) {
        this.input.focus();
      }
    });
  };

  onSelectChange = (value, options) => {
    const { record, handleSave } = this.props;
    const orign_waybill_quantity = Number(
      !record.waybill_quantity || record.waybill_quantity == -1 ? 0 : record.waybill_quantity
    );
    let hasSelected = false;
    if (value) {
      // 判断value值是否变化，变化说明切换了单号源
      hasSelected = true;
      this.setState({
        is_infinite: 1,
      });
    } else {
      hasSelected = false;
    }
    this.form.validateFields((error, fieldValues) => {
      const quantityForShow =
        fieldValues.quantityForShow !== undefined
          ? fieldValues.quantityForShow
          : orign_waybill_quantity;
      if (error) {
        return;
      }
      const type = options.props.sourcetype; // kop, taobao
      let source;
      record.selectData.forEach(item => {
        // 通过u_id来匹配source数据，source是下拉框的一整条数据
        item[type] &&
          item[type].forEach((values, index) => {
            const { u_id } = values;
            if (u_id == options.key) {
              source = item[type][index];
            }
          });
      });
      if (Object.keys(source).length > 0) {
        fieldValues.source = source;
        fieldValues.source_type = source.source_type;
        fieldValues.auth_id = source.auth_id;
        fieldValues.brand =
          source.brand || source.brand_code || source.brand_type || source.kb_code;
        fieldValues.hasSelected = hasSelected;
        fieldValues.quantity = quantityForShow - orign_waybill_quantity; // 1代表无限
        fieldValues.is_infinite = quantityForShow < 0 ? "1" : "0"; // 1代表无限
      }
      handleSave({ ...cloneDeep(record), ...fieldValues }, this.props);
    });
  };

  statusSelect = () => {
    this.save();
  };

  orderNumberSetting = () => {
    this.showModal(true);
  };

  onOk = () => {
    // 不限单号确定按钮
    const {
      quantity,
      addOrCut,
      quantityForShow,
      quantityForCalculate,
      is_infinite,
      quantityChanged,
    } = this.state;
    let num = Number(quantityForShow) + Number(quantityForCalculate);
    if (quantity == null && is_infinite == 0) {
      message.error("请填写添加或减少的单号数量！");
      return;
    }
    if (is_infinite == 1) {
      num = -1;
    }
    if (quantityForShow < 0 && quantityChanged) {
      // 防止当单号数量是无限时（-1），导致单号数量设置不准确
      num += 1;
    }
    if (
      is_infinite == 0 &&
      addOrCut == "decrease" &&
      Math.abs(quantityForCalculate) > (quantityForShow < 0 ? 0 : quantityForShow) // 防止当用户从无限单号切换到有限单号并做减少操作时且减少数量为0时，无法操作
    ) {
      message.error("减少单号数量不能大于现有可用单号数量！");
      return;
    }
    this.setState(
      {
        editing: false,
        quantityForShow: num,
        quantityChanged: false,
        quantity: null,
        quantityForCalculate: null,
      },
      () => {
        this.save();
      }
    );
    this.showModal(false);
  };

  showModal = open => {
    this.setState({
      visible: open,
    });
  };

  onCancel = () => {
    // 不限单号取消
    const { record } = this.props;
    const { quantityForShow } = this.state;
    if (record) {
      quantityForShow < 0 ? this.setState({ is_infinite: 1 }) : this.setState({ is_infinite: 0 });
    }
    this.setState({
      visible: false,
      addOrCut: "increase",
      quantity: null,
      quantityForCalculate: null,
    });
    this.showModal(false);
  };

  onRadioChange = e => {
    const { value } = e.target;
    if (value == 1) {
      // 无限单号
      this.setState({
        quantity: null, // 清空用户输入的单号数量
        quantityForCalculate: null,
      });
    }
    this.setState({
      is_infinite: value,
    });
  };

  onQuantityChange = value => {
    const { addOrCut } = this.state;
    if (addOrCut == "decrease" && value > 0) {
      this.setState({ quantityForCalculate: -value });
    } else {
      this.setState({ quantityForCalculate: value });
    }
    this.setState({
      quantity: value,
      is_infinite: 0,
      quantityChanged: true,
    });
  };

  formatter = value => {
    const reg = /^(\-)*(\d+)\.(\d\d).*$/;
    if (typeof value === "string") {
      return !isNaN(Number(value)) ? value.replace(reg, "$1$2.$3") : "";
    } else if (typeof value === "number") {
      return !isNaN(value) ? String(value).replace(reg, "$1$2.$3") : "";
    } else {
      return "";
    }
  };

  formatterNum = value => {
    const reg = /^[0-9]*$/;
    if (typeof value === "string") {
      return reg.test(value) ? value : "";
    } else if (typeof value === "number") {
      return reg.test(value) ? value : "";
    } else {
      return "";
    }
  };

  renderCell = form => {
    this.form = form;
    const {
      children,
      dataIndex,
      record,
      selectable,
      editprice,
      editstatus,
      isQuantity,
    } = this.props;
    const { editing, quantityForShow } = this.state;

    if (selectable) {
      return (
        <Form.Item style={{ margin: 0 }}>
          {form.getFieldDecorator(dataIndex, {
            initialValue: record[dataIndex].u_id,
          })(
            <Select
              placeholder="请选择单号源"
              onChange={this.onSelectChange}
              style={{ width: 400 }}
              getPopupContainer={triggerNode => triggerNode.parentNode}
            >
              {record.selectData &&
                record.selectData.map(item => {
                  const sourceType = Object.keys(item)[0];
                  const { label } = names[sourceType];
                  const sourceInfo = item[sourceType];
                  return (
                    <OptGroup label={label} key={sourceType} style={{ overflowY: "hidden" }}>
                      {sourceInfo.map(value => {
                        const { u_id } = value;
                        return (
                          <Option
                            style={{ width: "100%" }}
                            sourcetype={sourceType}
                            title={value.branch_name ? value.branch_name : value.account}
                            key={u_id}
                            value={u_id}
                          >
                            <Row type="flex" align="middle">
                              <Col span={11}>
                                <Row type="flex" align="middle" gutter={[8]}>
                                  <Col>
                                    <Avatar
                                      size="small"
                                      src={`//img.kuaidihelp.com/brand_logo/icon_${
                                        record.brand_type
                                      }.png`}
                                    />
                                  </Col>
                                  <Col>{value.brand_name}</Col>
                                </Row>
                              </Col>
                              <Col span={value.quantity == "" ? 13 : 8} style={textStyle}>
                                {value.branch_name ? value.branch_name : value.account}
                              </Col>
                              <Col span={value.quantity == "" ? 0 : 5} style={{ color: "red" }}>
                                {value.quantity !== "" ? `剩余${value.quantity}` : null}
                              </Col>
                            </Row>
                          </Option>
                        );
                      })}
                    </OptGroup>
                  );
                })}
            </Select>
          )}
        </Form.Item>
      );
    } else if (editprice) {
      return editing ? (
        <Form.Item style={{ margin: 0 }}>
          {form.getFieldDecorator(dataIndex, {
            initialValue: record[dataIndex],
          })(
            <InputNumber
              ref={node => (this.input = node)}
              onBlur={this.save}
              step={0.01}
              min={0.0}
              max={10000}
              precision={2}
              formatter={this.formatter}
            />
          )}
        </Form.Item>
      ) : (
        <>
          <span
            className="editable-cell-value-wrap"
            style={{ paddingRight: 24 }}
            onClick={this.toggleEdit.bind(this, true)}
          >
            {children}
          </span>
          元/单
        </>
      );
    } else if (editstatus) {
      return (
        <Form.Item style={{ marginBottom: 0 }}>
          {form.getFieldDecorator(dataIndex, {
            initialValue: record[dataIndex],
          })(
            <Select onSelect={this.statusSelect} style={{ width: 120 }}>
              <Option key="1" value="1">
                已开启
              </Option>
              <Option key="0" value="0">
                已关闭
              </Option>
            </Select>
          )}
        </Form.Item>
      );
    } else if (isQuantity) {
      return (
        <Form.Item style={{ marginBottom: 0 }}>
          {form.getFieldDecorator("quantityForShow", {
            initialValue: quantityForShow,
          })(
            <Row display="flex" justify="space-around">
              <Col span={12}>{quantityForShow >= 0 ? quantityForShow : "无限"}</Col>
              <Col span={12}>
                <a onClick={() => this.orderNumberSetting(record)}>编辑</a>
              </Col>
            </Row>
          )}
        </Form.Item>
      );
    } else {
      return children;
    }
  };

  render() {
    const {
      editable,
      dataIndex,
      selectable,
      isQuantity,
      title,
      key,
      record,
      index,
      handleSave,
      children,
      selectLoading,
      selectData,
      ...restProps
    } = this.props;
    const { visible, is_infinite, quantityForShow, quantityForCalculate } = this.state;

    const radioStyle = {
      display: "block",
      height: "30px",
      lineHeight: "30px",
    };
    const rowStyle = {
      marginLeft: "25px",
      marginTop: "10px",
      marginBottom: "10px",
    };
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
        ) : (
          children
        )}
        {isQuantity && (
          <Modal
            visible={visible}
            title="可用单号数量设置"
            onCancel={this.onCancel}
            onOk={this.onOk}
          >
            <Radio.Group onChange={this.onRadioChange} value={is_infinite}>
              <Radio style={radioStyle} value={1}>
                不限单号
              </Radio>
              <Row style={rowStyle}>
                <Col>
                  选择不限单号，则业务员使用设置的单号源打印电子面单没有限额，只要设置的单号源剩余单号源充足，则可以无限打单。
                </Col>
              </Row>
              <Radio style={radioStyle} value={0}>
                有限单号
                {is_infinite == 0 ? (
                  <span style={{ marginLeft: 200 }}>
                    可用单号数量：
                    {quantityForShow < 0 ? 0 : quantityForShow || 0}
                  </span>
                ) : null}
              </Radio>
              <Row style={rowStyle} type="flex">
                <Col>
                  <Select
                    value={this.state.addOrCut}
                    style={{ width: 100 }}
                    onChange={value => {
                      this.setState({
                        addOrCut: value,
                        is_infinite: 0,
                        quantityForCalculate: -quantityForCalculate, // 当下拉框值改变时，修改quantityForCalculate值的正负
                      });
                    }}
                  >
                    <Option key="increase" value="increase">
                      增加
                    </Option>
                    <Option key="decrease" value="decrease">
                      减少
                    </Option>
                  </Select>
                </Col>
                <Col push={1}>
                  <InputNumber
                    style={{ width: 250 }}
                    placeholder="请填写增加或者减少的单号数量"
                    onChange={this.onQuantityChange}
                    value={this.state.quantity}
                    min={0}
                    max={100000}
                    formatter={this.formatterNum}
                  />
                </Col>
              </Row>
              <Row style={rowStyle}>
                <Col>
                  选择有限单号，则业务员使用设置的单号源打印电子面单存在限额，限额的数量为以上输入框填写或显示的可用单号数量。
                </Col>
              </Row>
            </Radio.Group>
          </Modal>
        )}
      </td>
    );
  }
}
@connect(({ setter }) => ({
  setter,
}))
class EditableTable extends Component {
  constructor(props) {
    super(props);
    this.columns = [
      {
        title: "快递品牌",
        dataIndex: "brand_name",
        key: "brand_type",
        editable: true,
      },
      {
        title: "单号源选择",
        dataIndex: "source",
        key: "source_key",
        selectable: true,
        editable: true,
        width: 400,
      },
      {
        title: "单号价格",
        dataIndex: "price",
        editable: true,
        editprice: "true",
      },
      {
        title: "可用状态",
        dataIndex: "status",
        editable: true,
        editstatus: "true",
      },
      {
        title: "可用单号数量",
        dataIndex: "quantity",
        editable: true,
        isQuantity: true,
      },
    ];

    this.state = {
      dataSource: [],
      visiable: false,
      radioValue: 1,
      data: [],
      selectData: [],
    };
  }

  handleSave = (row, { dataIndex }) => {
    const newData = [...this.props.tableData];
    const index = newData.findIndex(item => row.id === item.id);
    const item = newData[index];
    let newDataList = "";
    if (JSON.stringify(row) != JSON.stringify(newData[index])) {
      newDataList = row;
    }
    newData.splice(index, 1, {
      ...item,
      ...row,
    });
    if (newDataList) {
      // 避免传递空数据
      this.dataSourceChange(newData, newDataList);
    }
  };

  dataSourceChange = (dataSource, ...arg) => {
    const { dataSourceChange } = this.props;
    if (dataSourceChange) {
      dataSourceChange(dataSource, arg[0]);
    }
  };

  render() {
    const { tableData } = this.props;
    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell,
      },
    };
    const columns = this.columns.map(col => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: record => {
          // 设置下拉框数据，筛选同一个快递品牌下的数据
          const {
            setter: { selectData },
          } = this.props;
          const brand = record.brand_type;
          if (selectData) {
            // 处理下拉框的数据
            const brands = Object.keys(selectData);
            const arr = [];

            if (brands.includes(brand)) {
              for (const key in selectData[brand]) {
                arr.push({ [key]: selectData[brand][key] });
              }
              record.selectData = arr;
            }
          }

          return {
            record,
            editable: col.editable,
            dataIndex: col.dataIndex,
            title: col.title,
            selectable: col.selectable,
            editprice: col.editprice,
            editstatus: col.editstatus,
            isQuantity: col.isQuantity, // 可用单号数量
            handleSave: this.handleSave,
          };
        },
      };
    });

    return (
      <div>
        <Table
          rowKey={record => record.id}
          components={components}
          rowClassName={() => "editable-row"}
          dataSource={tableData}
          columns={columns}
          pagination={false}
        />
      </div>
    );
  }
}

export default EditableTable;
